package com.gtlab1207.br_security.ctrls;


import com.gtlab1207.br_security.common.FileUtil;
import com.gtlab1207.br_security.common.Result;
import com.gtlab1207.br_security.services.CheckCertService;
import com.gtlab1207.br_security.services.CreateCertService;
import com.gtlab1207.br_security.services.DeleteCertService;
import com.gtlab1207.br_security.services.DownloadCertService;
import com.taoyuanx.ca.core.util.CertUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.client.RestTemplate;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.security.PrivateKey;
import java.security.cert.X509Certificate;

/**
 * 业务控制层
 *
 */

@RestController
@RequestMapping("/api/Cert")
public class CertManageCtrl extends BaseCtrl{

    @Value("${customize.server1.ip}")
    private String ip;
    @Value("${customize.server1.port}")
    private String port;
    @Value("${customize.server2.ip}")
    private String ip2;
    @Value("${customize.server2.port}")
    private String port2;
    @Autowired
    RestTemplate restTemplate;

    @Autowired
    CreateCertService createCertService;
    @Autowired
    CheckCertService checkCertService;
    @Autowired
    DeleteCertService deleteCertService;
    @Autowired
    DownloadCertService downloadCertService;
    // 证书的存放路径
    String baseCertPath="/Users/shier/Documents/cert/rsa/";

    /**
     * 证书创建层 用于创建证书 如果alias已存在 则创建失败
     * @param alias           用户名
     * @param password        密码
     * @param level           等级
     * @param name            真实姓名
     * @param role            角色
     * @param business        所属业务分类
     * @param template        模板分类
     * @param email           电子邮箱
     * @param sex             性别
     * @param organization    所属组织机构
     * @return true为创建成功，false创建失败
     * @throws Exception
     */
    @GetMapping("/createCert")
    public boolean createCert(@RequestParam(value = "alias", required = true, defaultValue = "666666") String alias,
                              @RequestParam(value = "password", required = true, defaultValue = "666666") String password,
                              @RequestParam(value = "level", required = true, defaultValue = "666666") String level,
                              @RequestParam(value = "name", required = true, defaultValue = "666666") String name,
                              @RequestParam(value = "role", required = true, defaultValue = "666666") String role,
                              @RequestParam(value = "business", required = true, defaultValue = "666666") String business,
                              @RequestParam(value = "template", required = true, defaultValue = "666666") String template,
                              @RequestParam(value = "email", required = true, defaultValue = "666666") String email,
                              @RequestParam(value = "sex", required = true, defaultValue = "666666") String sex,
                              @RequestParam(value = "organization", required = true, defaultValue = "666666") String organization,
                              HttpServletResponse response) throws Exception {

        // ca的路径
        String caCert_base64=baseCertPath+"ca/ca_base64.cer";
        String caPrivatePath=baseCertPath+"ca/ca_pri.pem";
        // 读取ca证书的内容
        X509Certificate CACert = CertUtil.readX509Cert(caCert_base64);
        PrivateKey privateKey = CertUtil.readPrivateKeyPem(caPrivatePath);

        boolean result = createCertService.CreateCert(CACert,privateKey,alias,password,level,name,role,business,template,email,sex,organization);

        if(!result){
            return result;
        }
        String path = baseCertPath + alias + "/" + alias + ".p12";
        downloadCertService.downloadCert(path,response);

        restTemplate.getForObject("http://" + ip + ":" + port + "/api/Cert/createRemoteCert?" +
                "alias={alias}&password={password}&level={level}&name={name}&role={role}&business={business}&template={template}&email={email}&sex={sex}&organization={organization}",
                Boolean.class,alias,password,level,name,role,business,template,email,sex,organization);
        restTemplate.getForObject("http://" + ip2 + ":" + port2 + "/api/Cert/createRemoteCert?" +
                "alias={alias}&password={password}&level={level}&name={name}&role={role}&business={business}&template={template}&email={email}&sex={sex}&organization={organization}",
                Boolean.class,alias,password,level,name,role,business,template,email,sex,organization);
        return result;
    }

    /**
     * 证书创建层 用于创建证书 如果alias已存在 则创建失败
     * @param alias           用户名
     * @param password        密码
     * @param level           等级
     * @param name            真实姓名
     * @param role            角色
     * @param business        所属业务分类
     * @param template        模板分类
     * @param email           电子邮箱
     * @param sex             性别
     * @param organization    所属组织机构
     * @return true为创建成功，false创建失败
     * @throws Exception
     */
    @GetMapping("/createRemoteCert") // 用于远程创建
    public boolean createRemoteCert(@RequestParam(value = "alias", required = true, defaultValue = "666666") String alias,
                              @RequestParam(value = "password", required = true, defaultValue = "666666") String password,
                              @RequestParam(value = "level", required = true, defaultValue = "666666") String level,
                              @RequestParam(value = "name", required = true, defaultValue = "666666") String name,
                              @RequestParam(value = "role", required = true, defaultValue = "666666") String role,
                              @RequestParam(value = "business", required = true, defaultValue = "666666") String business,
                              @RequestParam(value = "template", required = true, defaultValue = "666666") String template,
                              @RequestParam(value = "email", required = true, defaultValue = "666666") String email,
                              @RequestParam(value = "sex", required = true, defaultValue = "666666") String sex,
                              @RequestParam(value = "organization", required = true, defaultValue = "666666") String organization,
                              HttpServletResponse response) throws Exception {

        // 其他的证书路径
        String baseCertPath = "";
        // ca的路径
        String caCert_base64=baseCertPath+"ca/ca_base64.cer";
        String caPrivatePath=baseCertPath+"ca/ca_pri.pem";
        // 读取ca证书的内容
        X509Certificate CACert = CertUtil.readX509Cert(caCert_base64);
        PrivateKey privateKey = CertUtil.readPrivateKeyPem(caPrivatePath);

        boolean result = createCertService.CreateCert(CACert,privateKey,alias,password,level,name,role,business,template,email,sex,organization);

        if(!result){
            return result;
        }
        String path = baseCertPath + alias + "/" + alias + ".p12";

        return result;
    }

    @GetMapping("/updateCert")
    public boolean updateCert(@RequestParam(value = "alias", required = true, defaultValue = "666666") String alias,
                              @RequestParam(value = "password", required = true, defaultValue = "666666") String password,
                              @RequestParam(value = "level", required = true, defaultValue = "666666") String level,
                              @RequestParam(value = "name", required = true, defaultValue = "666666") String name,
                              @RequestParam(value = "role", required = true, defaultValue = "666666") String role,
                              @RequestParam(value = "business", required = true, defaultValue = "666666") String business,
                              @RequestParam(value = "template", required = true, defaultValue = "666666") String template,
                              @RequestParam(value = "email", required = true, defaultValue = "666666") String email,
                              @RequestParam(value = "sex", required = true, defaultValue = "666666") String sex,
                              @RequestParam(value = "organization", required = true, defaultValue = "666666") String organization,
                              HttpServletResponse response) throws Exception {

        deleteCert(alias);// 将原先的删除

        // ca的路径
        String caCert_base64 = baseCertPath + "ca/ca_base64.cer";
        String caPrivatePath = baseCertPath + "ca/ca_pri.pem";
        // 读取ca证书的内容
        X509Certificate CACert = CertUtil.readX509Cert(caCert_base64);
        PrivateKey privateKey = CertUtil.readPrivateKeyPem(caPrivatePath);

        boolean result = createCertService.CreateCert(CACert,privateKey,alias,password,level,name,role,business,template,email,sex,organization);

        if(!result){
            return result;
        }

        String path = baseCertPath + alias + "/" + alias + ".p12";
        downloadCertService.downloadCert(path,response);

        return result;
    }

    /**
     * 证书校验层 对证书的有效性 合法性进行了校验
     * @param alias         用户alias
     * @param password      用户密码
     * @return              true是成功 false是失败
     */
    @RequestMapping("/checkCert")
    public String checkCert(@RequestParam(value = "alias", required = true)String alias,
                             @RequestParam(value = "password", required = true)String password,
                             @RequestParam(value = "file", required = false) MultipartFile file){

        FileUtil.saveFile(file);

        // 路径后续做修改 这里的路径 应该是用户上传的p12证书的路径
        String certPath = baseCertPath + "uploaded/" + alias + ".p12";

        String result = null;
        try {
            result = checkCertService.CheckCert(alias, password, certPath);
        } catch (IOException e) {
            e.printStackTrace();
        }

        return result;
    }

    /**
     * 证书删除 便于管理员管理 及 及时删除失效证书
     * @param alias 证书名
     * @return      true为删除成功 false为删除失败
     */
    @GetMapping("/deleteCert")
    public boolean deleteCert(@RequestParam(value = "alias", required = true)String alias){

        if(alias.equals("ca")){
            return false;
        }
        boolean result = deleteCertService.DeleteCert( alias, baseCertPath + alias);
        System.out.println(result);
        return result;
    }

    /**
     * 检测证书时效性 如果失效 删除证书
     * @return
     */
    @GetMapping("/detectCert")
    public boolean detectCert(){
        boolean result = deleteCertService.DetectCert();
        return result;
    }
}
